package {package}.{obj.lower}.service.impl;

import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import com.neusoft.hifly.commons.lang.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.neusoft.hifly.commons.lang.LongUtil;
import com.neusoft.hifly.commons.lang.StringConstants;
import com.neusoft.hifly.commons.lang.StringUtil;
import com.neusoft.hifly.commons.exception.SystemErrorException;

import com.neusoft.hifly.core.token.TokenContextHolder;
import com.neusoft.hifly.core.log.annotation.LogType;
import com.neusoft.hifly.core.log.annotation.OperationLog;
import com.neusoft.hifly.core.token.filter.JwtInterceptor;
import cn.com.ctcloud.saas.core.basic.service.impl.CTSaaSBaseServiceImpl;
import cn.com.ctcloud.saas.tenant.log.util.LoggingThread;
import lombok.extern.slf4j.Slf4j;
import cn.com.ctcloud.saas.tenant.organ.domain.{obj}Obj;


/**
 * Title: {project.name}-{project.app}
 * <p>
 * Description: {obj.name} Service
 * <p>
 * Copyright: {project.copyright}
 * <p>
 * Company: {project.company}
 * 
 * @author {project.author}
 * @version {project.version}
 */
@Service
public class {obj}ServiceImpl extends CTSaaSBaseServiceImpl implements I{obj}Service {
	@Autowired(required = false)
	private I{obj}Dao {obj.hump}Dao;

	/**
	 * 保存对象
	 * 
	 * @param obj
	 *            对象
	 * @throws SystemErrorException
	 *             自定义异常
	 */
	@Override
	@OperationLog(method = LogType.UPDATE, msg = "{obj.name}")
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class, RuntimeException.class })
	public void saveOrUpdate(final {obj}Obj obj) throws SystemErrorException {
		if (obj == null ) {
			return;
		}

		final String name = StringUtils.trimToEmpty(obj.getName());
		if (StringUtils.isEmpty(name)) {
			throw new SystemErrorException("名称不能为空!");
		}

		if (LongUtil.isEmpty(obj.getOrganLogicId())) {
			obj.setOrganLogicId(TokenContextHolder.get().getOrganLogicId());
		}

		final {obj}Obj oldObj = {obj.hump}Dao.getByLogicId(obj.getLogicId());
		
		// 有ID的话要判断是否保存还是更新
		if (oldObj == null) {
			// 保存

			if (null != this.getByName(name)) {
				throw new SystemErrorException("名称 [ " + name + " ] 已存在!");
			}
			
			obj.setId(idWorker.nextId());
			if (LongUtil.isEmpty(obj.getLogicId())) {
				obj.setLogicId(idWorker.nextId());
			}
			obj.setUpdateTime(LocalDateTime.now());
			
			if (StringUtils.isEmpty(obj.getUpdatePerson())) {
				obj.setUpdatePerson(TokenContextHolder.get().getUserName());
			}
			
			this.setForm(obj, obj);
			
			
			{obj.hump}Dao.insert(obj);
			
		} else {
			// 更新
			if (!StringUtils.equals(oldObj.getName(), name)) {
				if (null != this.getByName(name)) {
					throw new SystemErrorException("名称 [ " + name + " ] 已存在!");
				}
			}

			this.setForm(obj, oldObj);
			
			oldObj.setUpdateTime(LocalDateTime.now());
			if (StringUtils.isEmpty(oldObj.getUpdatePerson())) {
				oldObj.setUpdatePerson(TokenContextHolder.get().getUserName());
			}
			
			{obj.hump}Dao.updateById(oldObj);

		}
	}
	
	/**
	 * 根据ID删除对象
	 * 
	 * @param logicId
	 *            对象ID
	 */
	@Override
	@OperationLog(method = LogType.DELETE, msg = "{obj.name}")
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class, RuntimeException.class })
	public void deleteByLogicId(final long logicId) {
		if (LongUtil.isEmpty(logicId)) {
			return null;
		}
		{obj.hump}Dao.deleteByLogicId(logicId);
	}
	
	/**
	 * 批量删除对象
	 * 
	 * @param logicIds
	 *            对象ID，多id使用英文逗号分隔
	 */
	@Override
	public void deleteByBatch(final String logicIds) {
		if (StringUtils.isEmpty(logicIds) ) {
			return;
		}
		final String[] logicIdArr = logicIds.split(StringConstants.STRING_SPLIT_FLAG_3);
		if (logicIdArr == null) {
			return;
		}
		for (final String logicId : logicIdArr) {
			if (StringUtils.isEmpty(logicId)) {
				continue;
			}
			this.deleteByLogicId(Long.parseLong(logicId));
		}
	}

	/**
	 * 根据id查询对象
	 * 
	 * @param logicId
	 *            对象logicId
	 * @return 对象
	 */
	@Override
	public {obj}Obj getByLogicId(final long logicId){
		if (LongUtil.isEmpty(logicId)) {
			return null;
		}
		return {obj.hump}Dao.getByLogicId(logicId);
	}

	/**
	 * 根据名称查询对象
	 *
	 * @param name
	 *            名称
	 * @return 对象
	 */
	@Override
	public {obj}Obj getByName(final String name) {
		if (StringUtils.isEmpty(name)) {
			return null;
		}
		final List<{obj}Obj> list = {obj.hump}Dao.findByName(name);
		if (CollectionUtils.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}

	/**
	 * 查询所有对象
	 * 
	 * @return 对象集合
	 */
	@Override
	public List<{obj}Obj> findAll() {	
		return {obj.hump}Dao.findAll();
	}

	/**
	 * 根据条件查询
	 * 
	 * @param property
	 *            参数。其中isLike:Boolean 是否模糊查询
	 * @return 集合
	 */
	@Override
	public List<{obj}Obj> search(Map<String, Object> property) {
		final QueryWrapper<{obj}Obj> queryWrapper = new QueryWrapper<{obj}Obj>();
		replaceProperty(property);
		createSql(property, queryWrapper, new String[] { "{order.field}", "UPDATE_TIME" });
		return {obj.hump}Dao.selectList(queryWrapper);
	}

	/**
	 * 根据条件查询
	 * 
	 * @param offset
	 *            当前页数
	 * @param limit
	 *            分页长度
	 * @param property
	 *            参数。其中isLike:Boolean 是否模糊查询
	 * @return 返回Map
	 */
	@Override
	public IPage<{obj}Obj> search(final int offset, final int limit, Map<String, Object> property) {
		final IPage<{obj}Obj> page = new Page<{obj}Obj>(offset, limit);
		final QueryWrapper<{obj}Obj> queryWrapper = new QueryWrapper<{obj}Obj>();
		replaceProperty(property);
		createSql(property, queryWrapper, new String[] { "{order.field}", "UPDATE_TIME" });
		return {obj.hump}Dao.selectPage(page, queryWrapper);
	}
	
	/**
	 * 复制信息
	 * 
	 * @param fromObj
	 *            原信息
	 * @param toObj
	 *            新信息
	 */
	private void setForm(final {obj}Obj fromObj, final {obj}Obj toObj) {
		{service.param}
	}

	/**
	 * 将对象属性替换成数据库列
	 * 
	 * @param property
	 *            参数
	 */
	private void replaceProperty(final Map<String, Object> property) {
		if (property != null) {
			{dao.search.replace}
		}
	}
}
